<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html>
<head>
<title>Painting with Cairo</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="GUI, GTK#, Cairo, drawing, Visual Basic, programming, Linux">
<meta name="description" content="Painting with Cairo">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content">


<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Drawing with Cairo</h1>

<p>
In this part of the Visual Basic GTK# tutorial, we will 
do some painting with the Cairo library.
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 

<p>
<b class="keyword">Cairo</b> is a library for creating 2D vector graphics. 
We can use it to draw our own widgets, charts or various effects or animations. 
</p>


<h2>Colors</h2>

<p>
In the first example, we will work with colors. A color is an object 
representing a combination of Red, Green, and Blue (RGB) intensity values.
Cairo valid RGB values are in the range 0 to 1. 
</p>

<pre class="code">
' ZetCode Mono Visual Basic GTK# tutorial
'
' This program draws three rectangles.
' The interiors are filled with
' different colors.
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Gtk
 
Public Class GtkVBApp
    Inherits Window
       
    Public Sub New
        
        MyBase.New("Colors")
        
        Me.InitUI

        Me.SetDefaultSize(360, 100)
        Me.SetPosition(WindowPosition.Center)
        AddHandler Me.DeleteEvent, AddressOf Me.OnDelete

        Me.ShowAll 
        
    End Sub
    
    Private Sub InitUI
        
        Dim darea As New DrawingArea
        AddHandler darea.ExposeEvent, AddressOf Me.OnExpose
        Me.Add(darea)

    End Sub
    
    Private Sub OnExpose(ByVal sender As Object, ByVal args As ExposeEventArgs)
    
        Dim cc As Cairo.Context = Gdk.CairoHelper.Create(sender.GdkWindow)
                
        Me.DrawColors(cc)
    
        Dim disposeTarget As IDisposable = CType(cc.Target, IDisposable)
        disposeTarget.Dispose
        
        Dim disposeContext As IDisposable = CType(cc, IDisposable)
        disposeContext.Dispose

    End Sub
    
    Private Sub DrawColors(ByVal cc As Cairo.Context)
    
        cc.SetSourceRGB(0.2, 0.23, 0.9)
        cc.Rectangle(10, 15, 90, 60)
        cc.Fill
         
        cc.SetSourceRGB(0.9, 0.1, 0.1)
        cc.Rectangle(130, 15, 90, 60)
        cc.Fill

        cc.SetSourceRGB(0.4, 0.9, 0.4)
        cc.Rectangle(250, 15, 90, 60)
        cc.Fill    
    
    End Sub
    
    
    Private Sub OnDelete(ByVal sender As Object, _
            ByVal args As DeleteEventArgs)
        Application.Quit
    End Sub

    Public Shared Sub Main
    
        Application.Init
        Dim app As New GtkVBApp
        Application.Run
        
    End Sub
 
End Class
</pre>

<p>
In our example, we will draw three rectangles and fill them with
three different colors. 
</p>

<pre>
vbnc -r:/usr/lib/mono/gtk-sharp-2.0/gtk-sharp.dll 
 -r:/usr/lib/mono/gtk-sharp-2.0/gdk-sharp.dll
 -r:/usr/lib/mono/2.0/Mono.Cairo.dll colors.vb
</pre>

<p>
Here is how we compile the example. 
</p>

<pre class="explanation">
 Dim darea As New DrawingArea
</pre>

<p>
We will be doing our drawing operations on the <b class="keyword">DrawingArea</b> 
widget. 
</p>

<pre class="explanation">
 AddHandler darea.ExposeEvent, AddressOf Me.OnExpose
</pre>

<p>
All drawing is done in a method, that we plug into
the <b class="keyword">ExposeEvent</b>.
</p>

<pre class="explanation">
 Dim cc As Cairo.Context = Gdk.CairoHelper.Create(sender.GdkWindow)
</pre>

<p>
We create the <b class="keyword">Cairo.Context</b> object from the
<b class="keyword">GdkWindow</b> of the drawing area. The context is an
object onto which we do all our drawings. 
</p>

<pre class="explanation">
 Me.DrawColors(cc)
</pre>

<p>
The actual drawing is delegated to the <b class="keyword">DrawColors</b> method. 
</p>

<pre class="explanation">
 Dim disposeTarget As IDisposable = CType(cc.Target, IDisposable)
 disposeTarget.Dispose
 
 Dim disposeContext As IDisposable = CType(cc, IDisposable)
 disposeContext.Dispose
</pre>

<p>
Here we dispose the resources, that were used during the drawing process. 
</p>


<pre class="explanation">
 cc.SetSourceRGB(0.2, 0.23, 0.9)
</pre>

<p>
The <b class="keyword">SetSourceRGB</b> method sets a color for the 
cairo context. The three parameters of the method are the color intensity
values. 
</p>

<pre class="explanation">
 cc.Rectangle(10, 15, 90, 60)
</pre>

<p>
We draw a rectangle. The first two parameters are the x, y coordinates of the
top left corner of the rectangle. The last two parameters are the width and height
of the rectangle. 
</p>


<pre class="explanation">
cc.Fill
</pre>

<p>
We fill the inside of the rectangle with the current color. 
</p>


<br>
<img src="/img/gui/vbgtk/colors.png" alt="Colors">
<div class="figure">Figure: Colors</div>


<h2>Basic shapes</h2>

<p>
The next example draws some basic shapes onto the window. 
</p>

<pre class="code">
' ZetCode Mono Visual Basic GTK# tutorial
'
' This program draws basic shapes
' available in Cairo
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Gtk
 
Public Class GtkVBApp
    Inherits Window
       
    Public Sub New
        
        MyBase.New("Basic Shapes")
        
        Me.InitUI

        Me.SetDefaultSize(400, 250)
        Me.SetPosition(WindowPosition.Center)
        AddHandler Me.DeleteEvent, AddressOf Me.OnDelete

        Me.ShowAll
        
    End Sub
    
    Private Sub InitUI
        
        Dim darea As New DrawingArea
        AddHandler darea.ExposeEvent, AddressOf Me.OnExpose
        Me.Add(darea)

    End Sub
    
    Private Sub OnExpose(ByVal sender As Object, ByVal args As ExposeEventArgs)
    
        Dim cc As Cairo.Context = Gdk.CairoHelper.Create(sender.GdkWindow)
                
        Me.DrawShapes(cc)
    
        Dim disposeTarget As IDisposable = CType(cc.Target, IDisposable)
        disposeTarget.Dispose
        
        Dim disposeContext As IDisposable = CType(cc, IDisposable)
        disposeContext.Dispose

    End Sub
    
    Private Sub DrawShapes(ByVal cc As Cairo.Context)
        
        cc.SetSourceRGB(0.5, 0.5, 0.5)

        cc.Rectangle(20, 20, 120, 80)
        cc.Rectangle(180, 20, 80, 80)
        cc.Fill

        cc.Arc(330, 60, 40, 0, 2*Math.PI)
        cc.Fill
        
        cc.Arc(90, 160, 40, Math.PI/4, Math.PI)
        cc.ClosePath
        cc.Fill

        cc.Translate(220, 180)
        cc.Scale(1, 0.7)
        cc.Arc(0, 0, 50, 0, 2*Math.PI)
        cc.Fill
    
    End Sub
    
    
    Private Sub OnDelete(ByVal sender As Object, _
            ByVal args As DeleteEventArgs)
        Application.Quit
    End Sub

    Public Shared Sub Main
    
        Application.Init
        Dim app As New GtkVBApp
        Application.Run
        
    End Sub
 
End Class
</pre>

<p>
In this example, we will create a rectangle, a square, a circle, an arc and an ellipse. 
</p>

<pre class="explanation">
 cc.Rectangle(20, 20, 120, 80)
 cc.Rectangle(180, 20, 80, 80)
 cc.Fill
</pre>

<p>
These lines draw a rectangle and a square. 
</p>

<pre class="explanation">
 cc.Arc(330, 60, 40, 0, 2*Math.PI)
 cc.Fill
</pre>

<p>
Here the <b class="keyword">Arc</b> method draws a full circle.
</p>

<pre class="explanation">
 cc.Translate(220, 180)
 cc.Scale(1, 0.7)
 cc.Arc(0, 0, 50, 0, 2*Math.PI)
 cc.Fill
</pre>

<p>
The <b class="keyword">Translate</b> method moves the object to a specific
point. If we want to draw an oval, we do some scaling first. Here the 
<b class="keyword">Scale</b> method shrinks the y axis.
</p>


<br>
<img src="/img/gui/vbgtk/shapes.png" alt="Basic shapes">
<div class="figure">Figure: Basic shapes</div>


<h2>Transparent rectangles</h2>

<p>
Transparency is the quality of being able to see through a material. The easiest way to understand 
transparency is to imagine a piece of glass or water. Technically, the rays of light can go
through the glass and this way we can see objects behind the glass.
</p>

<p>
In computer graphics, we can achieve transparency effects using alpha compositing. Alpha compositing
is the process of combining an image with a background to create the appearance of partial transparency. 
The composition process uses an alpha channel. (wikipedia.org, answers.com)
</p>

<pre class="code">
' ZetCode Mono Visual Basic GTK# tutorial
'
' This program draws ten
' rectangles with different
' levels of transparency
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Gtk
 
Public Class GtkVBApp
    Inherits Window
       
    Public Sub New
        
        MyBase.New("Transparent rectangles")
        
        Me.InitUI

        Me.SetDefaultSize(590, 90)
        Me.SetPosition(WindowPosition.Center)
        AddHandler Me.DeleteEvent, AddressOf Me.OnDelete

        Me.ShowAll
        
    End Sub
    
    Private Sub InitUI
        
        Dim darea As New DrawingArea
        AddHandler darea.ExposeEvent, AddressOf Me.OnExpose
        Me.Add(darea)

    End Sub
    
    Private Sub OnExpose(ByVal sender As Object, ByVal args As ExposeEventArgs)
    
        Dim cc As Cairo.Context = Gdk.CairoHelper.Create(sender.GdkWindow)
                
        Me.DrawRectangles(cc)
 
        Dim disposeTarget As IDisposable = CType(cc.Target, IDisposable)
        disposeTarget.Dispose()
        
        Dim disposeContext As IDisposable = CType(cc, IDisposable)
        disposeContext.Dispose()

    End Sub
    
    Private Sub DrawRectangles(ByVal cc As Cairo.Context)
    
        For i As Integer = 1 To 10        
            cc.SetSourceRGBA(0, 0, 1, i*0.1)
            cc.Rectangle(50*i, 20, 40, 40)
            cc.Fill  
        Next
    
    End Sub
    
    
    Private Sub OnDelete(ByVal sender As Object, _
            ByVal args As DeleteEventArgs)
        Application.Quit
    End Sub

    Public Shared Sub Main
    
        Application.Init
        Dim app As New GtkVBApp
        Application.Run
        
    End Sub
 
End Class
</pre>

<p>
In the example we will draw ten rectangles with different levels of transparency. 
</p>

<pre class="explanation">
 cc.SetSourceRGBA(0, 0, 1, i*0.1)
</pre>

<p>
The last parameter of the <b class="keyword">SetSourceRGBA</b> method is the
alpha transparency.
</p>


<br>
<img src="/img/gui/vbgtk/transparency.png" alt="Transparent rectangles">
<div class="figure">Figure: Transparent rectangles</div>


<h2>Donut</h2>

<p>
In the following example we create n complex shape by rotating a bunch of ellipses. 
</p>

<pre class="code">
' ZetCode Mono Visual Basic GTK# tutorial
'
' This program draws basic shapes
' available in Cairo
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Gtk
 
Public Class GtkVBApp
    Inherits Window
       
    Public Sub New
        
        MyBase.New("Donut")
        
        Me.InitUI

        Me.SetDefaultSize(400, 250)
        Me.SetPosition(WindowPosition.Center)
        AddHandler Me.DeleteEvent, AddressOf Me.OnDelete

        Me.ShowAll
        
    End Sub
    
    Private Sub InitUI
        
        Dim darea As New DrawingArea
        AddHandler darea.ExposeEvent, AddressOf Me.OnExpose
        Me.Add(darea)

    End Sub
    
    Private Sub OnExpose(ByVal sender As Object, ByVal args As ExposeEventArgs)
    
        Dim cc As Cairo.Context = Gdk.CairoHelper.Create(sender.GdkWindow)
                
        Me.DrawDonut(cc)
    
        Dim disposeTarget As IDisposable = CType(cc.Target, IDisposable)
        disposeTarget.Dispose
        
        Dim disposeContext As IDisposable = CType(cc, IDisposable)
        disposeContext.Dispose

    End Sub
    
    Private Sub DrawDonut(ByVal cc As Cairo.Context)
        
        cc.LineWidth = 0.5

        Dim width, height As Integer
        width = Allocation.Width
        height = Allocation.Height
       
        cc.Translate(width/2, height/2)
        cc.Arc(0, 0, 120, 0, 2*Math.PI)
        cc.Stroke
         
        cc.Save

        For i As Integer = 0 To 35
            cc.Rotate( i*Math.PI/36)
            cc.Scale(0.3, 1)
            cc.Arc(0, 0, 120, 0, 2*Math.PI)
            cc.Restore
            cc.Stroke
            cc.Save
        Next
    
    End Sub
    
    
    Private Sub OnDelete(ByVal sender As Object, _
            ByVal args As DeleteEventArgs)
        Application.Quit
    End Sub

    Public Shared Sub Main
    
        Application.Init
        Dim app As New GtkVBApp
        Application.Run
        
    End Sub
 
End Class
</pre>

<p>
In this example, we create a donut. The shape resembles a cookie, hence the name donut.
</p>

<pre class="explanation">
 cc.Translate(width/2, height/2)
 cc.Arc(0, 0, 120, 0, 2*Math.PI)
 cc.Stroke
</pre>

<p>
In the beginning there is an ellipse. 
</p>

<pre class="explanation">
 For i As Integer = 0 To 35
     cc.Rotate( i*Math.PI/36)
     cc.Scale(0.3, 1)
     cc.Arc(0, 0, 120, 0, 2*Math.PI)
     cc.Restore
     cc.Stroke
     cc.Save
 Next
</pre>

<p>
After several rotations, there is a donut.
</p>


<br>
<img src="/img/gui/vbgtk/donut.jpg" alt="Donut">
<div class="figure">Figure: Donut</div>


<h2>Drawing text</h2>

<p>
In the next example, we draw some text on the window. 
</p>

<pre class="code">
' ZetCode Mono Visual Basic GTK# tutorial
'
' This program draws text
' on the window
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Gtk
 
Public Class GtkVBApp
    Inherits Window
       
    Public Sub New
        
        MyBase.New("Soulmate")
        
        Me.InitUI

        Me.SetDefaultSize(400, 250)
        Me.SetPosition(WindowPosition.Center)
        AddHandler Me.DeleteEvent, AddressOf Me.OnDelete

        Me.ShowAll    
        
    End Sub
    
    Private Sub InitUI
        
        Dim darea As New DrawingArea
        AddHandler darea.ExposeEvent, AddressOf Me.OnExpose
        Me.Add(darea)

    End Sub
    
    Private Sub OnExpose(ByVal sender As Object, ByVal args As ExposeEventArgs)
    
        Dim cc As Cairo.Context = Gdk.CairoHelper.Create(sender.GdkWindow)
                
        Me.DrawLyrics(cc)
    
        Dim disposeTarget As IDisposable = CType(cc.Target, IDisposable)
        disposeTarget.Dispose
        
        Dim disposeContext As IDisposable = CType(cc, IDisposable)
        disposeContext.Dispose

    End Sub
    
    Private Sub DrawLyrics(ByVal cc As Cairo.Context)
        
        cc.SetSourceRGB(0.1, 0.1, 0.1)
         
        cc.SelectFontFace("Purisa", Cairo.FontSlant.Normal, Cairo.FontWeight.Bold)
        cc.SetFontSize(13)
       
        cc.MoveTo(20, 30)
        cc.ShowText("Most relationships seem so transitory")
        cc.MoveTo(20, 60)
        cc.ShowText("They're all good but not the permanent one")
        cc.MoveTo(20, 120)
        cc.ShowText("Who doesn't long for someone to hold")
        cc.MoveTo(20, 150)
        cc.ShowText("Who knows how to love without being told")
        cc.MoveTo(20, 180)
        cc.ShowText("Somebody tell me why I'm on my own")
        cc.MoveTo(20, 210)
        cc.ShowText("If there's a soulmate for everyone")

    End Sub
    
    
    Private Sub OnDelete(ByVal sender As Object, _
            ByVal args As DeleteEventArgs)
        Application.Quit
    End Sub

    Public Shared Sub Main
    
        Application.Init
        Dim app As New GtkVBApp
        Application.Run
        
    End Sub
 
End Class
</pre>

<p>
We display part of the lyrics from the Natasha Bedingfields Soulmate song. 
</p>

<pre class="explanation">
 cc.SelectFontFace("Purisa", Cairo.FontSlant.Normal, Cairo.FontWeight.Bold)
</pre>

<p>
Here we specify the font, that we use. Purisa bold.
</p>

<pre class="explanation">
 cc.SetFontSize(13)
</pre>

<p>
We specify the size of the font.
</p>

<pre class="explanation">
 cc.MoveTo(20, 30)
</pre>

<p>
We move to the point, where we will draw the text. 
</p>

<pre class="explanation">
 cc.ShowText("Most relationships seem so transitory")
</pre>

<p>
The <b class="keyword">ShowText</b> method draws text onto the window. 
</p>


<br>
<img src="/img/gui/vbgtk/soulmate.png" alt="Soulmate">
<div class="figure">Figure: Soulmate</div>


<hr class="btm">

<p>
In this chapter of the Visual Basic GTK# tutorial, we were painting 
with Cairo library.
</p>


<br> 
<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 
<br> 


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified May 25, 2009  <span class="copyright">&copy; 2007 - 2012 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>
